package com.pan.api.convert.impl;


import com.pan.api.anno.PanComment;
import com.pan.api.convert.ArgumentStrategy;
import com.pan.api.entity.ArgumentInformation;
import com.pan.api.entity.ParameterRequestType;
import org.springframework.web.bind.annotation.*;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ArgumentStrategyImpl
        extends ArgumentStrategy {
    public ArgumentStrategyImpl() {
    }

    @Override
    public List<ArgumentInformation> handle(Method method) {
        List<ArgumentInformation> resultList = new ArrayList<>();
        Parameter[] parameters = method.getParameters();
        System.out.println(method.toString());
        pan: for (Parameter param : parameters) {
            ArgumentInformation argumentInformation = new ArgumentInformation();
            qi: for (Annotation anno : param.getAnnotations()) {
                Class<? extends Annotation> annotationClass = anno.annotationType();
                System.out.println("debug annotation class: "+ annotationClass);
                if (anno instanceof PanComment panComment) {
                    String value = panComment.value();
                    argumentInformation.setComment(value);
                    if (param.getAnnotations().length == 1){
                        argumentInformation.setParamType(ParameterRequestType.Param);
                        argumentInformation.setParamClass(param.getType());
                        argumentInformation.setParamName(param.getName());
                    }
                }else if(anno instanceof PathVariable pathVariable) {
                    String value = pathVariable.value();
                    argumentInformation.setParamType(ParameterRequestType.Path);
                    argumentInformation.setParamClass(param.getType());
                    argumentInformation.setParamName(value.isEmpty() ? param.getName() : value);
                } else if (anno instanceof RequestBody) {
                    argumentInformation.setParamType(ParameterRequestType.Body);
                    argumentInformation.setParamClass(param.getType());
                    String paramName = param.getName();
                    argumentInformation.setParamName(paramName.matches("^arg\\d+$")?"body":paramName);
                } else if (anno instanceof RequestHeader requestHeader) {
                    String value = requestHeader.value();
                    argumentInformation.setParamType(ParameterRequestType.Head);
                    argumentInformation.setParamClass(param.getType());
                    argumentInformation.setParamName(value.isEmpty() ? param.getName() : value);
                } else if (anno instanceof  RequestAttribute requestAttribute){
                    String value = requestAttribute.value();
                    argumentInformation.setParamType(ParameterRequestType.Attr);
                    argumentInformation.setParamClass(param.getType());
                    argumentInformation.setParamName(value.length() == 0 ? param.getName() : value);
                } else if (anno instanceof RequestParam requestParam) {
//                    System.out.println("debug param.getName(): "+param.getName() );
//                    System.out.println("debug @RequestParam value: "+ requestParam.value());
//                    System.out.println("debug value.isEmpty(): "+requestParam.value().isEmpty());
//                    System.out.println("debug @RequestParam name: "+ requestParam.name());
                    String value = requestParam.value();
                    argumentInformation.setParamType(ParameterRequestType.Param);
                    argumentInformation.setParamClass(param.getType());
                    argumentInformation.setParamName(value.isEmpty() ? param.getName() : value);
//                    System.out.println("debug @RequestParma information: "+argumentInformation);
                }else{
                    argumentInformation.setParamType(ParameterRequestType.Param);
                    argumentInformation.setParamClass(param.getType());
                    argumentInformation.setParamName(param.getName());
                }
            }
            resultList.add(argumentInformation);
        }
        return resultList;
    }
}
